package com.taobao.tddl.monitor.sql;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.exception.ExceptionUtils;

import com.taobao.tddl.common.jdbc.Parameters;
import com.taobao.tddl.common.utils.extension.ExtensionLoader;
import com.taobao.tddl.common.utils.extension.ExtensionNotFoundException;
import com.taobao.tddl.common.utils.logger.Logger;
import com.taobao.tddl.common.utils.logger.LoggerFactory;

public class SqlMonitorHelper {

    private static final Logger logger      = LoggerFactory.getLogger(SqlMonitorHelper.class);
    static List<SqlMonitor>     sqlMonitors = null;

    static {
        List<Class> sqlMonitorClasses = ExtensionLoader.getAllExtendsionClass(SqlMonitor.class);
        if ((sqlMonitorClasses != null) && (!sqlMonitorClasses.isEmpty())) {
            sqlMonitors = new ArrayList();
            for (int i = sqlMonitorClasses.size() - 1; i >= 0; i--) {
                Class clazz = (Class) sqlMonitorClasses.get(i);
                try {
                    SqlMonitor monitor = (SqlMonitor) SqlMonitor.class.cast(clazz.newInstance());
                    sqlMonitors.add(monitor);
                } catch (Throwable e) {
                    throw new ExtensionNotFoundException("not found service provider for : "
                                                         + SqlMonitor.class.getName() + " caused by "
                                                         + ExceptionUtils.getFullStackTrace(e));
                }
            }
        }
    }

    public static String matrixSql(String sql, Parameters params, String appName) {
        if (sqlMonitors != null) {
            for (SqlMonitor sqlMonitor : sqlMonitors) {
                try {
                    sql = sqlMonitor.matrixSql(sql, params, appName);
                } catch (SqlMonitorBreakException e) {
                    break;
                } catch (SqlMonitorThrowException e) {
                    throw e;
                } catch (Throwable e) {
                    logger.error(e);
                }
            }
        }
        return sql;
    }

    public static String groupSql(String sql, Parameters params, String appName, String groupKey) {
        if (sqlMonitors != null) {
            for (SqlMonitor sqlMonitor : sqlMonitors) {
                try {
                    sql = sqlMonitor.groupSql(sql, params, appName, groupKey);
                } catch (SqlMonitorBreakException e) {
                    break;
                } catch (SqlMonitorThrowException e) {
                    throw e;
                } catch (Throwable e) {
                    logger.error(e);
                }
            }
        }
        return sql;
    }

    public static void atomSql(String sql, Statement stmt, String appName, String dbKey, String ip, String port) {
        if (sqlMonitors != null) {
            for (SqlMonitor sqlMonitor : sqlMonitors) {
                try {
                    sqlMonitor.atomSql(sql, stmt, appName, dbKey, ip, port);
                } catch (SqlMonitorBreakException e) {
                    break;
                } catch (SqlMonitorThrowException e) {
                    throw e;
                } catch (Throwable e) {
                    logger.error(e);
                }
            }
        }
    }
}
